/*
编译命令（请注意根据你的DTK环境调整-I和-L路径）：
hipcc -std=c++11 -I /opt/hyhal/hsa -L/opt/hyhal/hsa/lib -lhsa-runtime64  test_hsa_api.cpp -o test_hsa
*/

#include <hsa/hsa.h>
#include <stdio.h>
#include <stdlib.h>

#define CHECK_HSA(func) { \
    hsa_status_t status = func; \
    if (status != HSA_STATUS_SUCCESS) { \
        const char* err_msg; \
        hsa_status_string(status, &err_msg); \
        printf("[ERROR] %s failed: %s\n", #func, err_msg); \
        exit(1); \
    } \
}

void print_agent_info(hsa_agent_t agent) {
    // 获取设备类型
    hsa_device_type_t device_type;
    CHECK_HSA(hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type));

    // 获取代理名称
    char name[64] = {0}; // 初始化为0
    CHECK_HSA(hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, name));

    // 获取代理厂商名称
    char vendor[64] = {0};
    CHECK_HSA(hsa_agent_get_info(agent, HSA_AGENT_INFO_VENDOR_NAME, vendor));

    // 获取代理功能
    hsa_agent_feature_t features;
    CHECK_HSA(hsa_agent_get_info(agent, HSA_AGENT_INFO_FEATURE, &features));

    // 获取最大队列大小
    uint32_t queue_size = 0;
    CHECK_HSA(hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size));

    printf("Found %s agent:\n", (device_type == HSA_DEVICE_TYPE_CPU) ? "CPU" : "GPU");
    printf("  Name: %s\n", name);
    printf("  Vendor: %s\n", vendor);
    printf("  Max Queue Size: %u\n", queue_size);
    printf("  Features: %s%s\n",
           (features & HSA_AGENT_FEATURE_KERNEL_DISPATCH) ? "KERNEL_DISPATCH " : "",
           (features & HSA_AGENT_FEATURE_AGENT_DISPATCH) ? "AGENT_DISPATCH " : "");
    printf("\n");
}

void print_system_info() {
    // 获取系统时间频率
    uint64_t timestamp_frequency;
    CHECK_HSA(hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &timestamp_frequency));
    printf("System Timestamp Frequency: %lu Hz\n", timestamp_frequency);

    // 获取端序信息
    hsa_endianness_t endianness;
    CHECK_HSA(hsa_system_get_info(HSA_SYSTEM_INFO_ENDIANNESS, &endianness));
    printf("System Endianness: %s\n", endianness == HSA_ENDIANNESS_LITTLE ? "LITTLE" : "BIG");
    printf("\n");
}

int main() {
    // 初始化HSA运行时
    CHECK_HSA(hsa_init());
    printf("HSA runtime initialized successfully\n\n");

    // 打印系统信息
    printf("=== System Information ===\n");
    print_system_info();

    // 迭代所有代理并打印基本信息
    printf("=== Agent Information ===\n");
    CHECK_HSA(hsa_iterate_agents([](hsa_agent_t agent, void* data) -> hsa_status_t {
        print_agent_info(agent);
        return HSA_STATUS_SUCCESS;
    }, NULL));

    // 创建信号测试
    printf("=== Signal Test ===\n");
    hsa_signal_t signal;
    CHECK_HSA(hsa_signal_create(1, 0, NULL, &signal));

    hsa_signal_value_t initial_value = hsa_signal_load_relaxed(signal);
    printf("Signal created with initial value: %ld\n", initial_value);

    // 递减信号值
    hsa_signal_subtract_relaxed(signal, 1); // 此函数返回void，直接调用
    hsa_signal_value_t new_value = hsa_signal_load_relaxed(signal); // 重新加载值
    printf("Signal value after subtract: %ld\n", new_value);

    // 等待信号值为0 (这里因为信号初始值为1，我们减了1，所以已经是0，等待会立即返回)
    // 只是为了演示API的使用
    hsa_signal_value_t final_value = hsa_signal_wait_relaxed(signal, HSA_SIGNAL_CONDITION_EQ, 0, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);
    printf("Signal wait completed. Final value: %ld\n", final_value);

    CHECK_HSA(hsa_signal_destroy(signal));
    printf("Signal destroyed\n\n");

    // 关闭HSA运行时
    CHECK_HSA(hsa_shut_down());
    printf("HSA runtime shut down successfully\n");

    return 0;
}